package com.snail.generator.utils;

import com.snail.generator.common.WebContext;
import com.snail.generator.entity.DataSourceInfo;
import com.snail.generator.mapper.impl.MysqlGeneratorMapper;
import com.snail.generator.mapper.impl.PostgresqlGeneratorMapper;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.intellij.lang.annotations.Language;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Collections;
import java.util.List;

@Component
@RequiredArgsConstructor
public class SqlUtils {

    public static String getDriverClassName(DataSourceInfo info) {
        return switch (info.type.toLowerCase()) {
            case "mysql" -> "com.mysql.cj.jdbc.Driver";
            case "postgresql" -> "org.postgresql.Driver";
            default -> throw new RuntimeException("暂不支持的数据库类型：" + info.type);
        };
    }

    public static String getUrl(DataSourceInfo info) {
        return switch (info.type.toLowerCase()) {
            case "mysql" -> "jdbc:mysql://" + info.host + ":" + info.port + "/";
            case "postgresql" -> "jdbc:postgresql://" + info.host + ":" + info.port + "/";
            default -> throw new RuntimeException("暂不支持的数据库类型：" + info.type);
        };
    }

    public static Class<?> getMapperClass(DataSourceInfo info) {
        return switch (info.type.toLowerCase()) {
            case "mysql" -> MysqlGeneratorMapper.class;
            case "postgresql" -> PostgresqlGeneratorMapper.class;
            default -> throw new RuntimeException("暂不支持的数据库类型：" + info.type);
        };
    }

    public interface Consumer<T> {
        void accept(T t) throws Exception;
    }

    public static void execute(@Language("sql") String sql, Consumer<ResultSet> consumer) {
        execute(sql, Collections.emptyList(), consumer);
    }

    @SneakyThrows
    public static void execute(@Language("sql") String sql, List<Object> params, Consumer<ResultSet> consumer) {
        Connection connection = WebContext.getDataSourceConnection();
        PreparedStatement pStmt = connection.prepareStatement(sql);
        for (int i = 0; i < params.size(); i++) {
            pStmt.setObject(i + 1, params.get(i));
        }
        ResultSet resultSet = pStmt.executeQuery();
        consumer.accept(resultSet);

        resultSet.close();
        pStmt.close();
    }

}
